//! 事务系统性能测试
//! 
//! 验证事务管理器的性能表现

#[cfg(test)]
mod tests {
    use super::super::transaction::*;
    use super::super::page::PageManager;
    use std::sync::Arc;
    use std::time::Instant;
    use tempfile::tempdir;

    #[test]
    fn test_transaction_throughput() {
        let temp_dir = tempdir().unwrap();
        let wal_path = temp_dir.path().join("perf.wal").to_string_lossy().to_string();
        let page_manager = Arc::new(PageManager::new(1000));
        let tx_manager = TransactionManager::new(page_manager, wal_path).unwrap();
        
        let num_transactions = 1000;
        let start_time = Instant::now();
        
        // 测试事务吞吐量
        for _i in 0..num_transactions {
            let tx = tx_manager.begin_transaction(IsolationLevel::ReadCommitted, false).unwrap();
            tx_manager.commit_transaction(tx).unwrap();
        }
        
        let elapsed = start_time.elapsed();
        let throughput = num_transactions as f64 / elapsed.as_secs_f64();
        
        println!("事务吞吐量: {:.2} 事务/秒", throughput);
        println!("平均事务延迟: {:.2} 毫秒", elapsed.as_millis() as f64 / num_transactions as f64);
        
        // 验证统计信息
        let stats = tx_manager.get_stats();
        assert_eq!(stats.total_transactions, num_transactions);
        assert_eq!(stats.committed_transactions, num_transactions);
        assert_eq!(stats.active_transactions, 0);
        
        // 性能要求：至少1000 TPS
        assert!(throughput >= 1000.0, "事务吞吐量过低: {:.2} TPS", throughput);
    }
    
    #[test]
    fn test_concurrent_transactions() {
        let temp_dir = tempdir().unwrap();
        let wal_path = temp_dir.path().join("concurrent.wal").to_string_lossy().to_string();
        let page_manager = Arc::new(PageManager::new(1000));
        let tx_manager = Arc::new(TransactionManager::new(page_manager, wal_path).unwrap());
        
        let num_threads = 4;
        let transactions_per_thread = 250;
        let start_time = Instant::now();
        
        // 并发事务测试
        let handles: Vec<_> = (0..num_threads).map(|_| {
            let tx_manager = tx_manager.clone();
            std::thread::spawn(move || {
                for _i in 0..transactions_per_thread {
                    let tx = tx_manager.begin_transaction(IsolationLevel::ReadCommitted, false).unwrap();
                    tx_manager.commit_transaction(tx).unwrap();
                }
            })
        }).collect();
        
        // 等待所有线程完成
        for handle in handles {
            handle.join().unwrap();
        }
        
        let elapsed = start_time.elapsed();
        let total_transactions = num_threads * transactions_per_thread;
        let throughput = total_transactions as f64 / elapsed.as_secs_f64();
        
        println!("并发事务吞吐量: {:.2} 事务/秒", throughput);
        println!("并发度: {} 线程", num_threads);
        
        // 验证统计信息
        let stats = tx_manager.get_stats();
        assert_eq!(stats.total_transactions, total_transactions as u64);
        assert_eq!(stats.committed_transactions, total_transactions as u64);
        assert_eq!(stats.active_transactions, 0);
        
        // 并发性能要求：至少2000 TPS
        assert!(throughput >= 2000.0, "并发事务吞吐量过低: {:.2} TPS", throughput);
    }
    
    #[test]
    fn test_readonly_transaction_performance() {
        let temp_dir = tempdir().unwrap();
        let wal_path = temp_dir.path().join("readonly.wal").to_string_lossy().to_string();
        let page_manager = Arc::new(PageManager::new(1000));
        let tx_manager = TransactionManager::new(page_manager, wal_path).unwrap();
        
        let num_transactions = 2000;
        let start_time = Instant::now();
        
        // 测试只读事务性能
        for _i in 0..num_transactions {
            let tx = tx_manager.begin_transaction(IsolationLevel::ReadCommitted, true).unwrap();
            tx_manager.commit_transaction(tx).unwrap();
        }
        
        let elapsed = start_time.elapsed();
        let throughput = num_transactions as f64 / elapsed.as_secs_f64();
        
        println!("只读事务吞吐量: {:.2} 事务/秒", throughput);
        
        // 只读事务应该更快，要求至少5000 TPS
        assert!(throughput >= 5000.0, "只读事务吞吐量过低: {:.2} TPS", throughput);
    }
    
    #[test]
    fn test_wal_write_performance() {
        let temp_dir = tempdir().unwrap();
        let wal_path = temp_dir.path().join("wal_perf.wal").to_string_lossy().to_string();
        let wal_manager = WalManager::new(wal_path).unwrap();
        
        let num_records = 1000;
        let start_time = Instant::now();
        
        // 测试WAL写入性能
        for i in 0..num_records {
            wal_manager.write_transaction_begin(i as u64).unwrap();
            
            let record_type = WalRecordType::Insert {
                page_id: i as u64,
                slot_id: 0,
                old_data: None,
                new_data: vec![1, 2, 3, 4, 5],
            };
            wal_manager.write_record(i as u64, record_type).unwrap();
            
            wal_manager.write_transaction_commit(i as u64).unwrap();
        }
        
        // 刷新到磁盘
        wal_manager.flush().unwrap();
        
        let elapsed = start_time.elapsed();
        let throughput = (num_records * 3) as f64 / elapsed.as_secs_f64(); // 每个事务3条记录
        
        println!("WAL写入吞吐量: {:.2} 记录/秒", throughput);
        
        // WAL写入性能要求：至少10000 记录/秒
        assert!(throughput >= 10000.0, "WAL写入吞吐量过低: {:.2} 记录/秒", throughput);
    }
    
    #[test]
    fn test_lock_manager_performance() {
        let lock_manager = LockManager::new();
        let num_locks = 1000;
        let start_time = Instant::now();
        
        // 测试锁获取和释放性能
        let mut lock_ids = Vec::new();
        for i in 0..num_locks {
            let lock_id = format!("lock_{}", i);
            lock_manager.acquire_lock(1, lock_id.clone(), LockMode::Shared).unwrap();
            lock_ids.push(lock_id);
        }
        
        for lock_id in lock_ids {
            lock_manager.release_lock(1, &lock_id).unwrap();
        }
        
        let elapsed = start_time.elapsed();
        let throughput = (num_locks * 2) as f64 / elapsed.as_secs_f64(); // 获取+释放
        
        println!("锁操作吞吐量: {:.2} 操作/秒", throughput);
        
        // 锁操作性能要求：至少50000 操作/秒
        assert!(throughput >= 50000.0, "锁操作吞吐量过低: {:.2} 操作/秒", throughput);
    }
    
    #[test]
    fn test_deadlock_detection_performance() {
        let lock_manager = LockManager::new();
        let deadlock_detector = DeadlockDetector::new();
        
        let num_detections = 100;
        let start_time = Instant::now();
        
        // 测试死锁检测性能
        for _i in 0..num_detections {
            let _result = deadlock_detector.detect_deadlock(&lock_manager).unwrap();
        }
        
        let elapsed = start_time.elapsed();
        let throughput = num_detections as f64 / elapsed.as_secs_f64();
        
        println!("死锁检测吞吐量: {:.2} 检测/秒", throughput);
        
        // 死锁检测性能要求：至少1000 检测/秒
        assert!(throughput >= 1000.0, "死锁检测吞吐量过低: {:.2} 检测/秒", throughput);
    }
    
    #[test]
    fn test_transaction_rollback_performance() {
        let temp_dir = tempdir().unwrap();
        let wal_path = temp_dir.path().join("rollback.wal").to_string_lossy().to_string();
        let page_manager = Arc::new(PageManager::new(1000));
        let tx_manager = TransactionManager::new(page_manager, wal_path).unwrap();
        
        let num_transactions = 500;
        let start_time = Instant::now();
        
        // 测试事务回滚性能
        for _i in 0..num_transactions {
            let tx = tx_manager.begin_transaction(IsolationLevel::ReadCommitted, false).unwrap();
            tx_manager.rollback_transaction(tx).unwrap();
        }
        
        let elapsed = start_time.elapsed();
        let throughput = num_transactions as f64 / elapsed.as_secs_f64();
        
        println!("事务回滚吞吐量: {:.2} 事务/秒", throughput);
        
        // 验证统计信息
        let stats = tx_manager.get_stats();
        assert_eq!(stats.total_transactions, num_transactions);
        assert_eq!(stats.rolled_back_transactions, num_transactions);
        assert_eq!(stats.active_transactions, 0);
        
        // 回滚性能要求：至少800 TPS
        assert!(throughput >= 800.0, "事务回滚吞吐量过低: {:.2} TPS", throughput);
    }
    
    #[test]
    fn test_mixed_workload_performance() {
        let temp_dir = tempdir().unwrap();
        let wal_path = temp_dir.path().join("mixed.wal").to_string_lossy().to_string();
        let page_manager = Arc::new(PageManager::new(1000));
        let tx_manager = TransactionManager::new(page_manager, wal_path).unwrap();
        
        let total_transactions = 1000;
        let readonly_ratio = 0.7; // 70%只读事务
        let rollback_ratio = 0.1; // 10%回滚事务
        
        let start_time = Instant::now();
        
        // 混合工作负载测试
        for i in 0..total_transactions {
            let ratio = i as f64 / total_transactions as f64;
            
            if ratio < readonly_ratio {
                // 只读事务
                let tx = tx_manager.begin_transaction(IsolationLevel::ReadCommitted, true).unwrap();
                tx_manager.commit_transaction(tx).unwrap();
            } else if ratio < readonly_ratio + rollback_ratio {
                // 回滚事务
                let tx = tx_manager.begin_transaction(IsolationLevel::ReadCommitted, false).unwrap();
                tx_manager.rollback_transaction(tx).unwrap();
            } else {
                // 普通读写事务
                let tx = tx_manager.begin_transaction(IsolationLevel::ReadCommitted, false).unwrap();
                tx_manager.commit_transaction(tx).unwrap();
            }
        }
        
        let elapsed = start_time.elapsed();
        let throughput = total_transactions as f64 / elapsed.as_secs_f64();
        
        println!("混合工作负载吞吐量: {:.2} 事务/秒", throughput);
        println!("只读事务比例: {:.1}%", readonly_ratio * 100.0);
        println!("回滚事务比例: {:.1}%", rollback_ratio * 100.0);
        
        // 验证统计信息
        let stats = tx_manager.get_stats();
        assert_eq!(stats.total_transactions, total_transactions);
        
        // 混合工作负载性能要求：至少1500 TPS
        assert!(throughput >= 1500.0, "混合工作负载吞吐量过低: {:.2} TPS", throughput);
    }
}
